/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       int_array.h

	$Header: /game/int_array.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef INT_ARRAY_H_INCLUDED
#define INT_ARRAY_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

// ---------------------------------------------------------------
// array of integers with some simple operands defined
// ---------------------------------------------------------------
template <size_t size>
class t_int_array
{
public:
	enum
	{
		k_size = size
	};

	t_int_array();

	int const* get() const;
	int        get_count() const;
	int        get_sum() const;
	void       set( int arg );

	int& operator[](int arg);
	int  operator[](int arg) const;
	t_int_array& operator+=( t_int_array const& arg );
	t_int_array& operator+=( int arg );
	t_int_array& operator-=( t_int_array const& arg );
	t_int_array& operator-=( int arg );
	t_int_array& operator*=( int arg );
	t_int_array& operator/=( int arg );
	bool         operator==( t_int_array const& arg ) const;
	bool         operator!=( t_int_array const& arg ) const;
protected:
	int m_data[size];
};

// ---------------------------------------------------------------
// inlines for int array
// ---------------------------------------------------------------
template <size_t size>
inline t_int_array<size>::t_int_array()
{
	set(0);
}

template <size_t size>
inline int const* t_int_array<size>::get() const
{
	return m_data;
}

template <size_t size>
inline int t_int_array<size>::get_count() const
{
	int const* ptr = m_data;
	int        count = size;
	int        result = 0;

	while (count--)
		if (*ptr++ != 0)
			result++;
	return result;
}

template <size_t size>
inline int t_int_array<size>::get_sum() const
{
	int const* ptr = m_data;
	int        count = size;
	int        result = 0;

	while (count--)
		result += *ptr++;
	return result;
}

template <size_t size>
inline void t_int_array<size>::set( int arg )
{
	int* ptr = m_data;
	int  count = size;

	while (count--)
		*ptr++ = arg;
}

template <size_t size>
inline int& t_int_array<size>::operator[](int arg)
{
	return m_data[arg];
}

template <size_t size>
inline int t_int_array<size>::operator[](int arg) const
{
	return m_data[arg];
}

template <size_t size>
inline t_int_array<size>& t_int_array<size>::operator+=( t_int_array const& arg )
{
	int*       dest = m_data;
	int const* source = arg.m_data;
	int        count  = size;

	while (count--)
		*dest++ += *source++;
	return *this;
}

template <size_t size>
inline t_int_array<size>& t_int_array<size>::operator+=( int arg )
{
	int* ptr   = m_data;
	int  count = size;

	while (count--)
		*ptr++ += arg;
	return *this;
}

template <size_t size>
inline t_int_array<size>& t_int_array<size>::operator-=( t_int_array const& arg )
{
	int const* source = arg.m_data;
	int*       dest   = m_data;
	int        count = size;

	while (count--)
		*dest++ -= *source++;
	return *this;
}

template <size_t size>
inline t_int_array<size>& t_int_array<size>::operator-=( int arg )
{
	int* ptr   = m_data;
	int  count = size;

	while (count--)
		*ptr++ -= arg;
	return *this;
}

template <size_t size>
inline t_int_array<size>& t_int_array<size>::operator*=( int arg )
{
	int* ptr   = m_data;
	int  count = size;

	while (count--)
		*ptr++ *= arg;
	return *this;
}

template <size_t size>
inline t_int_array<size>& t_int_array<size>::operator/=( int arg )
{
	int* ptr   = m_data;
	int  count = size;

	while (count--)
		*ptr++ /= arg;
	return *this;
}

template <size_t size>
inline bool t_int_array<size>::operator==( t_int_array const& arg ) const
{
	return memcmp( m_data, arg.m_data, size * sizeof(int)) == 0;
}

template <size_t size>
inline bool t_int_array<size>::operator!=( t_int_array const& arg ) const
{
	return memcmp( m_data, arg.m_data, size * sizeof(int)) != 0;
}

// ---------------------------------------------------------------
// associated binary functions
// ---------------------------------------------------------------
template <size_t size>
inline t_int_array<size> operator+( t_int_array<size> left, t_int_array<size> const& right )
{
	left += right;
	return left;
}

template <size_t size>
inline t_int_array<size> operator+( t_int_array<size> left, int right )
{
	left += right;
	return left;
}

template <size_t size>
inline t_int_array<size> operator+( int left, t_int_array<size> right )
{
	right += left;
	return right;
}

template <size_t size>
inline t_int_array<size> operator-( t_int_array<size> left, t_int_array<size> const& right )
{
	left -= right;
	return left;
}

template <size_t size>
inline t_int_array<size> operator-( t_int_array<size> left, int right )
{
	left -= right;
	return left;
}

template <size_t size>
inline t_int_array<size> operator*( t_int_array<size> left, int right )
{
	left *= right;
	return left;
}

template <size_t size>
inline t_int_array<size> operator*( int left, t_int_array<size> right )
{
	right *= left;
	return right;
}

template <size_t size>
inline t_int_array<size> operator/( t_int_array<size> left, int right )
{
	left /= right;
	return left;
}

#endif // INT_ARRAY_H_INCLUDED